一、概述
solr是一个war包,项目里可以通过solrj与solr交互,solr具备数据持久化的功能,可以储存需要进行搜索的数据,solr可以通过索引查询到对应数据,它可以在大量数据检索时提升检索效率。其他检索方案还有luncene(solr基于lucene)es。
solr对中文拆词支持不友好,因此需要使用IKAnalyzer拆词器。 https://www.cnblogs.com/zuge/p/5753971.htmlhttp://blog.csdn.net/qq_30739519/article/details/51437296
1.1 IK中文分词器
配置IK实际上是给solr新建了一个filedType,只要某个属性(fieId)是这个类型,这个属性就会使用IK分词
1.2 管理页面
- 包含了 solr 数据的新增,删除,修改三个功能.
- 数据支持很多种格式:json 或 xml 等
- 新增时,必须包含对 id 的新增.
- 每次新增,Solr 会新建一个 SolrDocument 对象.这个对象存储新增内容.
- 把 SolrDocument 理解成实体类.
- 包含了 Solr 的 schema.xml 中配置的所有 field
- 新增时有什么属性,最终显示时就只有什么属性.
二、使用示例
2.1 java使用Demo
依赖
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>5.3.1</version>
</dependency>配置
<bean id="solrClient" class="org.apache.solr.client.solrj.impl.CloudSolrCli ent">
<constructor-arg type="java.lang.String" value="192.168.249.131:2181,192.168.249.131:2182,192. 168.249.131:2183"></constructor-arg>
<property name="defaultCollection" value="collection1"></property>
</bean>代码实现
// 存储
@Resource
private CloudSolrClient solrClient;
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", item.getId());
doc.addField("item_title", item.getTitle());
doc.addField("item_sell_point", item.getSellPoint());
doc.addField("item_price",item.getPrice() );
doc.addField("item_image", item.getImage());
doc.addField("item_category_name", cat.getName());
doc.addField("item_desc", desc.getItemDesc());
solrClient.add(doc);
solrClient.commit();
// 查询
SolrQuery params = new SolrQuery();
//设置分页条件
params.setStart(rows*(page-1));
params.setRows(rows);
//设置条件
params.setQuery("item_keywords:"+query);
//设置高亮
params.setHighlight(true);
params.addHighlightField("item_title");
params.setHighlightSimplePre("<span style='color:red'>");
params.setHighlightSimplePost("</span>");
QueryResponse response = solrClient.query(params);
List<TbItemChild> listChild = new ArrayList<>();
//未高亮内容
SolrDocumentList listSolr = response.getResults();
//高亮内容
Map<String, Map<String, List<String>>> hh = response.getHighlighting();
for (SolrDocument doc : listSolr) {
TbItemChild child = new TbItemChild();
child.setId(Long.parseLong(doc.getFieldValue("id"). toString()));
List<String> list = hh.get(doc.getFieldValue("id")).get("item_title");
if(list!=null&&list.size()>0){
child.setTitle(list.get(0));
}else{
child.setTitle(doc.getFieldValue("item_title").toSt ring());
}
child.setPrice((Long)doc.getFieldValue("item_price" ));
Object image = doc.getFieldValue("item_image");
child.setImages(image==null||image.equals("")?new String[1]:image.toString().split(","));
child.setSellPoint(doc.getFieldValue("item_sell_poi nt").toString());
listChild.add(child);
}
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("itemList", listChild);
resultMap.put("totalPages",listSolr.getNumFound()%rows==0?listSolr.getNumFound() /rows:listSolr.getNumFound()/rows+1);
return resultMap;2.2 管理页面操作数据
<!-- 增加或修改,id不存在新增,存在修改 -->
<doc>
<field name="id">change.me</field>
<field name="title">change.me</field>
</doc>
<!-- 删除 -->
<delete>
<id>id 内容</id>
</delete>
<!-- 删除全部 -->
<delete>
<query>*:*</query>
</delete>
<commit/>
<!-- 查询全部 -->
*:* 查询全部2.3 配置
<!-- 在 /conf/schema.xml 中配置配置业务字段 -->
<field name="item_title" type="text_ik" indexed="true" stored="true"/>
<field name="item_sell_point" type="text_ik" indexed="true" stored="true"/>
<field name="item_price" type="long" indexed="true" stored="true"/>
<field name="item_image" type="string" indexed="false" stored="true" />
<field name="item_category_name" type="string" indexed="true" stored="true" />
<field name="item_desc" type="text_ik" indexed="true" stored="false" />
<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="item_title" dest="item_keywords"/>
<copyField source="item_sell_point" dest="item_keywords"/>
<copyField source="item_category_name" dest="item_keywords"/>
<copyField source="item_desc" dest="item_keywords"/>三、安装
3.1 常规安装
流程
- 安装Tomcat
- 解压solr
- 把 solr 下的dist目录solr-4.10.3.war部署到 Tomcat\webapps下(去掉版本号)。
- 启动 Tomcat解压缩 war 包
- 把solr下example/lib/ext 目录下的所有的 jar 包,添加到 solr 的工程中(\WEB-INF\lib目录下)。
配置
- solrHome配置 创建一个 solrhome 。solr 下的/example/solr 目录就是一个 solrhome。复制此目录到放置目录改名为solrhome 在solr 工程的 web.xml 文件修改配置
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>solrhome地址</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>- 中文分析器配置 把IKAnalyzer2012FF_u1.jar 添加到 solr 工程的 lib 目录下 创建WEB-INF/classes文件夹 把扩展词典、停用词词典、配置文件放到 solr 工程的 WEB-INF/classes 目录下。 修改 Solrhome 的 schema.xml 文件,配置一个 FieldType,使用 IKAnalyzer
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>- 业务域配置 域相当于数据库的表字段,用户存放数据,因此用户根据业务需要去定义相关的Field(域),一般来说,每一种对应着一种数据,用户对同一种数据进行相同的操作。 域的常用属性: · name:指定域的名称 · type:指定域的类型 · indexed:是否索引 · stored:是否存储 · required:是否必须 multiValued:是否多值
修改solrhome的schema.xml 文件 设置业务系统 Field
<field name="item_goodsid" type="long" indexed="true" stored="true"/>
<field name="item_title" type="text_ik" indexed="true" stored="true"/>
<field name="item_price" type="double" indexed="true" stored="true"/>
<field name="item_image" type="string" indexed="false" stored="true" />
<field name="item_category" type="string" indexed="true" stored="true" />
<field name="item_seller" type="text_ik" indexed="true" stored="true" />
<field name="item_brand" type="string" indexed="true" stored="true" />复制域的作用在于将某一个Field中的数据复制到另一个域中
<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="item_title" dest="item_keywords"/>
<copyField source="item_category" dest="item_keywords"/>
<copyField source="item_seller" dest="item_keywords"/>
<copyField source="item_brand" dest="item_keywords"/>需要动态扩充字段时,需要使用动态域。
<dynamicField name="item_spec_*" type="string" indexed="true" stored="true" />3.2 Solr集群--SolrCloud
olrCloud 是基于 Solr 和Zookeeper的分布式搜索方案,它的主要思想是使用 Zookeeper作为集群的配置信息中心。
它有几个特色功能: 1)集中式的配置信息 2)自动容错 3)近实时搜索 4)查询时自动负载均衡
系统架构
【1】物理结构 三个 Solr 实例( 每个实例包括两个 Core),组成一个 SolrCloud。 【2】逻辑结构 索引集合包括两个 Shard(shard1 和 shard2),shard1 和 shard2 分别由三个 Core 组成,其中一个 Leader 两个 Replication,Leader 是由 zookeeper 选举产生,zookeeper 控制每个shard上三个 Core 的索引数据一致,解决高可用问题。 用户发起索引请求分别从 shard1 和 shard2 上获取,解决高并发问题。 (1)Collection Collection 在 SolrCloud 集群中是一个逻辑意义上的完整的索引结构。它常常被划分为一个或多个 Shard(分片),它们使用相同的配置信息。 比如:针对商品信息搜索可以创建一个 collection。 collection=shard1+shard2+....+shardX (2) Core 每个 Core 是 Solr 中一个独立运行单位,提供 索引和搜索服务。一个 shard 需要由一个Core 或多个 Core 组成。由于 collection 由多个 shard 组成所以 collection 一般由多个 core 组成。 (3)Master 或 Slave Master 是 master-slave 结构中的主结点(通常说主服务器),Slave 是 master-slave 结构中的从结点(通常说从服务器或备服务器)。同一个 Shard 下 master 和 slave 存储的数据是一致的,这是为了达到高可用目的。 (4)Shard Collection 的逻辑分片。每个 Shard 被化成一个或者多个 replication,通过选举确定哪个是 Leader。
搭建SolrCloud
修改每个solr的 web.xml 文件, 关联solrhome
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>/usr/local/solrhomes/solrhome-1</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>(1)修改每个 tomcat实例 bin 目录下的 catalina.sh 文件 把此配置添加到catalina.sh中( 第234行 ) : JAVA_OPTS="-DzkHost=192.168.25.140:2181,192.168.25.140:2182,192.168.25.140:2183" JAVA_OPTS ,顾名思义,是用来设置JVM相关运行参数的变量 . 此配置用于在tomcat启动时找到 zookeeper集群。 (2)配置 solrCloud 相关的配置。每个 solrhome 下都有一个 solr.xml,把其中的 ip 及端口号配置好(是对应的tomcat的IP和端口)。 solrhomes/solrhome-1/solr.xml,每个都需要修改。
<solrcloud>
<str name="host">192.168.25.140</str>
<int name="hostPort">8180</int>
<str name="hostContext">${hostContext:solr}</str>
<int name="zkClientTimeout">${zkClientTimeout:30000}</int>
<bool name="genericCoreNodeNames">${genericCoreNodeNames:true}</bool>
</solrcloud>(3) 让 zookeeper 统一管理配置文件。需要把 solrhome下collection1/conf 目录上传到zookeeper。上传任意 solrhome 中的配置文件即可。 我们需要使用solr给我们提供的工具上传配置文件: solr-4.10.3/example/scripts/cloud-scripts/zkcli.sh 将solr-4.10.3压缩包上传到linux,解压,然后进入solr-4.10.3/example/scripts/cloud-scripts目录 ,执行下列命令
./zkcli.sh -zkhost 192.168.25.140:2181,192.168.25.140:2182,192.168.25.140:2183 -cmd upconfig
-confdir /usr/local/solrhomes/solrhome-1/collection1/conf -confname myconf
#参数解释
#-zkhost :指定zookeeper地址列表
#-cmd :指定命令。upconfig 为上传配置的命令
#-confdir : 配置文件所在目录
#-confname : 配置名称(4) 启动集群 启动每个 tomcat 实例。要保证 zookeeper 集群是启动状态。 ---- 知识点小贴士 ----- 如果你想让某个文件夹下都可以执行,使用以下命令实现 chmod -R 777 solr-cloud (5)访问集群 地址栏输入 http://192.168.25.140:8180/solr ,可以看到Solr集群版的界面
使用
项目连接 在SolrJ中提供一个叫做CloudSolrServer的类,它是SolrServer的子类,用于连接solrCloud 它的构造参数就是zookeeper的地址列表,另外它要求要指定defaultCollection属性(默认的 collection名称) 我们现在修改springDataSolrDemo工程的配置文件 ,把原来的solr-server注销,替换为CloudSolrServer .指定构造参数为地址列表,设置默认 collection名称
<!-- solr服务器地址
<solr:solr-server id="solrServer" url="http://192.168.25.129:8080/solr" />
-->
<bean id="solrServer" class="org.apache.solr.client.solrj.impl.CloudSolrServer">
<constructor-arg value="192.168.25.140:2181,192.168.25.140:2182,192.168.25.140:2183" />
<property name="defaultCollection" value="collection1"></property>
</bean>分片配置 (1)创建新的 Collection 进行分片处理。在浏览器输入以下地址,创建新的Collection
http://192.168.25.140:8180/solr/admin/collections?action=CREATE&name=collection2&numShards=2&replicationFactor=2
参数:
name:将被创建的集合的名字
numShards:集合创建时需要创建逻辑碎片的个数
replicationFactor:分片的副本数。
看到这个提示表示成功